lib/deploy: Also install HMAC file into /boot
authorJonathan Lebon <jonathan@jlebon.com>
Tue, 29 Oct 2019 20:45:29 +0000 (16:45 -0400)
committerJonathan Lebon <jonathan@jlebon.com>
Tue, 29 Oct 2019 20:45:29 +0000 (16:45 -0400)
To allow for FIPS mode, we need to also install the HMAC file from
`/usr/lib/modules` to `/boot` alongside the kernel image where the
`fips` dracut module will find it. For details, see:

https://github.com/coreos/fedora-coreos-tracker/issues/302

Note I didn't include the file in the boot checksum since it's itself a
checksum of the kernel, so we don't really gain much here other than
potentially causing an unnecessary bootcsum bump.

src/libostree/ostree-sysroot-deploy.c
tests/libtest.sh
tests/test-admin-deploy-none.sh

index 15db0bf17c19b2931486840e8765bf3d54bb4e91..a09c354b93534f509430e3d96c73dd0401765562 100644 (file)
@@ -878,6 +878,8 @@ typedef struct {
   int   boot_dfd;
   char *kernel_srcpath;
   char *kernel_namever;
+  char *kernel_hmac_srcpath;
+  char *kernel_hmac_namever;
   char *initramfs_srcpath;
   char *initramfs_namever;
   char *devicetree_srcpath;
@@ -890,6 +892,8 @@ _ostree_kernel_layout_free (OstreeKernelLayout *layout)
   glnx_close_fd (&layout->boot_dfd);
   g_free (layout->kernel_srcpath);
   g_free (layout->kernel_namever);
+  g_free (layout->kernel_hmac_srcpath);
+  g_free (layout->kernel_hmac_namever);
   g_free (layout->initramfs_srcpath);
   g_free (layout->initramfs_namever);
   g_free (layout->devicetree_srcpath);
@@ -1032,6 +1036,16 @@ get_kernel_from_tree_usrlib_modules (int                  deployment_dfd,
   g_clear_object (&in);
   glnx_close_fd (&fd);
 
+  /* And finally, look for any HMAC file. This is needed for FIPS mode on some distros. */
+  if (!glnx_fstatat_allow_noent (ret_layout->boot_dfd, ".vmlinuz.hmac", NULL, 0, error))
+    return FALSE;
+  if (errno == 0)
+    {
+      ret_layout->kernel_hmac_srcpath = g_strdup (".vmlinuz.hmac");
+      /* Name it as dracut expects it: https://github.com/dracutdevs/dracut/blob/225e4b94cbdb702cf512490dcd2ad9ca5f5b22c1/modules.d/01fips/fips.sh#L129 */
+      ret_layout->kernel_hmac_namever = g_strdup_printf (".%s.hmac", ret_layout->kernel_namever);
+    }
+
   char hexdigest[OSTREE_SHA256_STRING_LEN+1];
   ot_checksum_get_hexdigest (&checksum, hexdigest, sizeof (hexdigest));
   ret_layout->bootcsum = g_strdup (hexdigest);
@@ -1686,6 +1700,20 @@ install_deployment_kernel (OstreeSysroot   *sysroot,
         }
     }
 
+  if (kernel_layout->kernel_hmac_srcpath)
+    {
+      if (!glnx_fstatat_allow_noent (bootcsum_dfd, kernel_layout->kernel_hmac_namever, &stbuf, 0, error))
+        return FALSE;
+      if (errno == ENOENT)
+        {
+          if (!install_into_boot (sepolicy, kernel_layout->boot_dfd, kernel_layout->kernel_hmac_srcpath,
+                                  bootcsum_dfd, kernel_layout->kernel_hmac_namever,
+                                  sysroot->debug_flags,
+                                  cancellable, error))
+            return FALSE;
+        }
+    }
+
   g_autofree char *contents = NULL;
   if (!glnx_fstatat_allow_noent (deployment_dfd, "usr/lib/os-release", &stbuf, 0, error))
     return FALSE;
index 8832e63ccc239bb29e3f3bf9928372e5b8671c4b..ba00073a10a787f51679db3cbdc1c3152c03baf2 100755 (executable)
@@ -395,6 +395,8 @@ setup_os_repository () {
     mkdir -p usr/bin ${bootdir} usr/lib/modules/${kver} usr/share usr/etc
     kernel_path=${bootdir}/vmlinuz
     initramfs_path=${bootdir}/initramfs.img
+    # the HMAC file is only in /usr/lib/modules
+    hmac_path=usr/lib/modules/${kver}/.vmlinuz.hmac
     # /usr/lib/modules just uses "vmlinuz", since the version is in the module
     # directory name.
     if [[ $bootdir != usr/lib/modules/* ]]; then
@@ -403,6 +405,7 @@ setup_os_repository () {
     fi
     echo "a kernel" > ${kernel_path}
     echo "an initramfs" > ${initramfs_path}
+    echo "an hmac file" > ${hmac_path}
     bootcsum=$(cat ${kernel_path} ${initramfs_path} | sha256sum | cut -f 1 -d ' ')
     export bootcsum
     # Add the checksum for legacy dirs (/boot, /usr/lib/ostree-boot), but not
index 66a1491fc7c87b4c4ed462f093c658677d5ef018..09dee62490520c0382d46383ab15983a0d30f3c1 100755 (executable)
@@ -43,6 +43,7 @@ ${CMD_PREFIX} ostree admin deploy --karg=root=LABEL=MOO --karg=quiet --os testos
 assert_file_has_content out.txt "Bootloader updated.*"
 assert_file_has_content sysroot/boot/loader/entries/ostree-1-testos.conf 'options.* root=LABEL=MOO'
 assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/vmlinuz-3.6.0 'a kernel'
+assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/.vmlinuz-3.6.0.hmac  'an hmac file'
 assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/initramfs-3.6.0.img 'an initramfs'
 echo "ok generate bls config on first deployment"